import java.awt.Point;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

/**
 * This is the Knight's Tour Game where the user uses the knight piece
 * from a chess game and has to visit every coordinate on the chess board
 * without going back on the same square that he previously visited.
 * 
 * @author Sabrina Gaudreau
 * @version January 24, 2010
 */
public class GameKnight
{
    private Board board;
    private Knight knight;
    private Scanner in;

    /**
     * Constructor for objects of class GameKnight
     * Place knight at position (0,0)
     * 
     * @author Sabrina Gaudreau
     */
    public GameKnight(){
        this.board = new Board();
        this.knight = new Knight(0,0); // make a new knight at coordinates (0,0)
        this.in = new Scanner(System.in);
        board.placePiece(0,0, "K"); // let the board know where the knight is located
    }

    /**
     * Launches the game by instantiating a new game and calling play() on it
     * @author Sabrina Gaudreau
     */
    public static void main(String[] args) throws IOException{
        GameKnight game = new GameKnight();
        game.play();
    }
    
    /**
     * Check to see if the move the user wants to do is legal or not. If
     * it is illegal tell the user.
     * 
     * @author Sabrina Gaudreau
     * @param x
     * @param y
     */
    public void placeKnight(int x, int y){
        //check if coordinates are out of bounds
        if(x >= Board.SIZE || x < 0 || y >= Board.SIZE || y < 0){
            System.out.println("Out of Bounds, Not a legal move!");
        }
        else if(legalMove(x,y)){ // check if coordinates are a legal move
            int oldx = knight.getX();
            int oldy = knight.getY();
            board.placePiece(oldx,oldy, "*"); // knight was there previously
            knight.move(x,y); // move the knight to the coordinates
            board.placePiece(x, y, "K"); // tell the board the knight is there
            knight = new Knight(x, y); // make a new knight so that all the 
            //possible moves can be recalculated
        }
        else{
            System.out.println("Not a legal move!");
        }
    }
    
    /**
     * Checks if the attempted move is in accordance
     * with the rules of the game.
     * 
     * @author Sabrina Gaudreau, modified by Jordan Beland
     * @param x
     * @param y
     * @return If it is a legal move
     */
    public boolean legalMove(int x, int y){
        ArrayList<Point> moves = knight.getMoves();
            for(Point p : moves){
                if(x == p.x && y == p.y){
                    if(board.getSquare(x, y) == "|_|")return true;
                }
            }
        return false;
    }
    
    /**
     * This outputs the current state of the board
     * 
     * @author: Sabrina Gaudreau
     */
    public void play() throws IOException
    {
        String inputMove;
        board.print();    
   
        while(hasWon() != true && hasLost() != true){
            System.out.println("Where would you like to move?");
            System.out.println("Enter Q9 to stop playing");
            // the view available moves is just for me to test things right now but
            // could be modified to help the user later on.
            System.out.println("Enter M9 to view available moves");
            inputMove = in.nextLine();
            
            int movx = board.convertx(inputMove);
            int movy = board.converty(inputMove);
            if(movx == 8 && movy == 8){
                break;
            }
            else if(movx == 9 && movy == 8){
                ArrayList<Point> moves = knight.getMoves();
                for(Point p : moves){
                    System.out.println(p.x);
                    System.out.println(p.y);
                }
            }
            else{
                placeKnight(movx, movy);
                board.print();
            }
        }       
        board.print();
        
        if(hasWon()){
            System.out.println("You Won!!! :D");
        }
        
        else if(hasLost()){
            System.out.println("You Lost! :(");
        }
    }
    
    /**
     * Checks to see if the horse has gone in all the squares of the board,
     * if so, the user has won.
     * 
     * @author Sabrina Gaudreau
     * @return Boolean user has won = True
     */
    // I do not know if this works... needs to be tested
    public boolean hasWon(){
        for(int j = 0; j < Board.SIZE; j++){
            for(int i = 0; i < Board.SIZE; i++){
                if(board.getSquare(j, i) == "|_|"){
                    return false;
                }
            }
        }
        return true;
    }
    
    /**Checks to see if the horse has no possible moves and not all the
     * squares of the board have been visited. The user has than lost.
     * 
     * @author Sabrina Gaudreau, modified by Jordan Beland
     * @return Boolean user has lost = True
     */
    public boolean hasLost(){
        ArrayList<Point> moves = this.knight.getMoves();
        for(Point p : moves){
        	if(this.board.getSquare(p.x, p.y) == "|_|")return false;
        }
        return true;
    }
    
}
